package cn.bonoon.services.plugins;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import cn.bonoon.core.plugins.ShortcutMenuService;
import cn.bonoon.entities.plugins.ShortcutMenuEntity;
import cn.bonoon.kernel.events.OperateEvent;
import cn.bonoon.kernel.menus.IShortcutInfo;
import cn.bonoon.kernel.menus.MenuInfo;
import cn.bonoon.kernel.menus.ModuleManager;
import cn.bonoon.kernel.support.IOperator;
import cn.bonoon.kernel.support.services.AbstractService;
import cn.bonoon.kernel.util.StringHelper;

@Service
@Transactional(readOnly = true)
public class ShortcutMenuServiceImpl extends AbstractService<ShortcutMenuEntity> implements ShortcutMenuService {

	@Autowired
	private ModuleManager moduleManager;

	@Override
	public int count(IOperator opt, String moduleId) {
		String ql = "select count(x) from ShortcutMenuEntity x where x.owner=? and x.moduleId=?";
		return __single(Number.class, ql, opt.getId(), moduleId).intValue();
	}

	@Override
	public List<ShortcutMenuEntity> get(IOperator opt, String moduleId) {
		return _get(opt, moduleId);
	}
	
	private List<ShortcutMenuEntity> _get(IOperator opt, String moduleId) {
		String ql = "from ShortcutMenuEntity x where x.owner=? and x.moduleId=? order by x.ordinal asc, x.createAt asc";
		return __list(ShortcutMenuEntity.class, ql, opt.getId(), moduleId);
	}
	
	@Override
	public Integer max_ordinal(IOperator opt, String moduleId) {
		return _max_ordinal(opt, moduleId);
	}

	private Integer _max_ordinal(IOperator opt, String moduleId) {
		String ql = "select max(x.ordinal) from ShortcutMenuEntity x where x.owner=? and x.moduleId=?";
		return __first(Integer.class, ql, opt.getId(), moduleId);
	}

	private ShortcutMenuEntity _save(IOperator opt, String mid, String rename, Integer type) {
		IShortcutInfo item = moduleManager.shortcut(mid);
		Assert.notNull(item, "无法找到菜单！");
		ShortcutMenuEntity entity = new ShortcutMenuEntity();
		entity.setMenuId(mid);
		entity.setName(StringHelper.isNotEmpty(rename) ? rename : item.getName());
		entity.setType(type);
		entity.setOwner(opt.getId());
		entity.setCreateAt(new Date());
		String moduleId = type == 0 ? moduleManager.module().getId() : item.getModule().getId();
		Integer max_ordinal = _max_ordinal(opt, moduleId);
		entity.setOrdinal(max_ordinal == null ? 0 : max_ordinal + 1);
		entity.setModuleId(moduleId);
		return entity;
	}

	@Override
	@Transactional
	public void save(IOperator opt, String mid, String rename, Integer type) {
		if (type == 2) {
			ShortcutMenuEntity entity_0 = _save(opt, mid, rename, 0);
			ShortcutMenuEntity entity_1 = _save(opt, mid, rename, 1);
			entityManager.persist(entity_0);
			entityManager.persist(entity_1);
		} else {
			ShortcutMenuEntity entity = _save(opt, mid, rename, type);
			entityManager.persist(entity);
		}
	}
	
	private void _reorder(List<ShortcutMenuEntity> menus) {
		if (null == menus)
			return;
		
		for (int i = 0; i < menus.size(); i++) {
			ShortcutMenuEntity menu = menus.get(i);
			menu.setOrdinal(i);
			entityManager.merge(menu);
		}
	}
	
	@Override
	protected void __delete(OperateEvent event, ShortcutMenuEntity entity) {
		super.__delete(event, entity);
		_reorder(_get(event, entity.getModuleId())); // 删除后对此菜单所在的系统的所有菜单重新排序
	}
	
	@Override
	@Transactional
	public void sort(IOperator opt, Long[] ids) {
		if (null == ids)
			return;

		for (int i = 0; i < ids.length; i++) {
			ShortcutMenuEntity entity = __get(ids[i]);
			entity.setOrdinal(i);
			entityManager.merge(entity);
		}
	}

	@Override
	@Transactional
	public void update_module(IOperator opt, Long id, Integer type) {
		ShortcutMenuEntity entity = __get(id);
		String old_moduleId = entity.getModuleId();
		entity.setType(type);
		MenuInfo menu = moduleManager.menu(entity.getMenuId());
		String new_moduleId = type.equals(0) ? moduleManager.module().getId() : menu.getModule().getId();
		Integer max_ordinal = _max_ordinal(opt, new_moduleId);
		entity.setOrdinal(max_ordinal == null ? 0 : max_ordinal + 1);
		entity.setModuleId(new_moduleId);
		entityManager.merge(entity);

		_reorder(_get(opt, old_moduleId)); // 对此菜单所在的子系统的所有菜单重新排序
	}

//	private void _sort(List<ShortcutMenuEntity> sms, ShortcutMenuEntity entity, int source_ordinal, int target_ordinal) {
//		int i = 0;
//		for (ShortcutMenuEntity sm : sms) {
//			if (sm == entity)
//				continue;
//
//			if (source_ordinal > target_ordinal) { // 向前移
//				if (i < target_ordinal || i > source_ordinal) {
//					sm.setOrdinal(i);
//				} else if (i >= target_ordinal && i < source_ordinal) {
//					sm.setOrdinal(i + 1);
//				}
//			} else { // 向后移
//				if (i < source_ordinal || i > target_ordinal) {
//					sm.setOrdinal(i);
//				} else if (i > source_ordinal && i <= target_ordinal) {
//					sm.setOrdinal(i - 1);
//				}
//			}
//			entityManager.merge(sm);
//			i++;
//		}
//		entity.setOrdinal(target_ordinal);
//		entityManager.merge(entity);
//	}

}
